/********************************************************************************
 * Copyright (c)2016-2020, ShenZhen WanJiaAn Technology CO.,LTD.
 * All Rights Reserved.
 *
 * File Name     : McuSoc.c
 * Author        : joki.zhu
 * Date          : 2020-07-03
 *
 * Record        :
 * 1.Date        : 2020-07-03
 *   Author      : joki.zhu
 *   Modification: Created file
 ********************************************************************************/
#include "McuSoc.h"
#include "app_common.h"
#include "hi_uartmsg.h"
#include "Upgrade.h"
#include "ProductManager.h"
#include "DevGpio.h"
#include "OsdDraw.h"

#ifdef YD_PROTOCOL
#include "DOTSdkMedia.h"
#endif /* YD_PROTOCOL */

extern HI_UARTMSG_SOCPOWER_TYPE_E g_enSocPowerType;

//static int gs_batteryLevel[10] = {5500, 5790, 6080, 6370, 6660, 6950, 7240, 7530, 7820, 8110, 8400};
static int gs_batteryLevel[10] = {6024, 6240, 6480, 6720, 6960, 7200, 7440, 7680, 7920, 8160};
static char gs_mcuState = 1;


int mcusoc_set_led_state(unsigned char value)
{
 	int i = 0;
    HI_UARTMSG_PARM_S  stSendMsg = {0};
    
    memset(&stSendMsg, 0, sizeof(stSendMsg));
    stSendMsg.u32MsgId = HI_UARTMSG_S2M_SET_LED_DATA;
    stSendMsg.data[i++] = value;
    stSendMsg.dataLen = i;
    
    HI_UARTMSG_SendMsg(&stSendMsg);

	LOGD("set led state: %#x\n", value);
	
	return 0;
}

int mcusoc_get_pir_switch()
{

}

int mcusoc_set_pir_switch(char bEnable)
{
	unsigned char val = 0;
    int i = 0;
    HI_UARTMSG_PARM_S  stSendMsg = {0};
    
	if (bEnable == 1) {
		val = 0x1;
	} else {
		val = 0x0;
	}
	
    memset(&stSendMsg, 0, sizeof(stSendMsg));
    stSendMsg.u32MsgId = HI_UARTMSG_S2M_SET_PIR_SWITCH;
    stSendMsg.data[i++] = val;
    stSendMsg.dataLen = i;
    
    HI_UARTMSG_SendMsg(&stSendMsg);

	LOGD("set pir switch: %d\n", val);

	return 0;
}

int mcusoc_get_pir_sensitivity(int *pValue)
{
    if (pValue == NULL) {
        LOGE("Params is invalid\n");
        return -1;
    }

	HI_UARTMSG_PARM_S  stSendMsg = {0};
	HI_UARTMSG_PARM_S  stWaitMsg = {0};
	HI_U32 timeoutMs = 1000;
	HI_S32 ret;
	static char errCnt = 0;

	stSendMsg.u32MsgId = HI_UARTMSG_S2M_GET_PIR_SENSITIVITY;
	stWaitMsg.dataLen = 3;
	stWaitMsg.u32MsgId = HI_UARTMSG_M2S_GET_PIR_SENSITIVITY_ACK;
	ret = HI_UARTMSG_SendMsgAndWaitMsg(&stSendMsg, &stWaitMsg, timeoutMs);
	if (0 != ret)
	{
		LOGE("HI_UARTMSG_SendMsgAndWaitMsg fail %d\n", ret);
		if (++errCnt >= 2) {
            mcusoc_set_reset("mcusoc_get_pir_sensitivity failed");
		}
		return -1;
	}
	else
	{  
        *pValue = stWaitMsg.data[0];
        LOGI("get pir sensiitvity: %d\n", *pValue);
    }

    return 0;
}

int mcusoc_set_pir_sensitivity(int value)
{
    int i = 0;
    HI_UARTMSG_PARM_S  stSendMsg = {0};

    memset(&stSendMsg, 0, sizeof(stSendMsg));
    stSendMsg.u32MsgId = HI_UARTMSG_S2M_SET_PIR_SENSITIVITY;
    stSendMsg.data[i++] = (unsigned char)value;
    stSendMsg.dataLen = i;

    HI_UARTMSG_SendMsg(&stSendMsg);
    LOGD("set pir sensiitvity: %d\n", value);

    return 0;
}

int mcusoc_set_pir_delay_wakeup_time(PIR_DELAY_WAKEUP_ATTR_S stPirDelayAttr)
{
	int i = 0;
    HI_UARTMSG_PARM_S  stSendMsg = {0};
    
    memset(&stSendMsg, 0, sizeof(stSendMsg));
    stSendMsg.u32MsgId = HI_UARTMSG_S2M_SET_PIR_DELAY_TIME;
    stSendMsg.data[i++] = stPirDelayAttr.detectTimeSec;
    stSendMsg.data[i++] = stPirDelayAttr.triggerTimeSec;
    stSendMsg.data[i++] = stPirDelayAttr.intervalTimeSec;
    stSendMsg.dataLen = i;
    
    HI_UARTMSG_SendMsg(&stSendMsg);
	
	return 0;
}

int mcusoc_get_pir_delay_wakeup_time(PIR_DELAY_WAKEUP_ATTR_S *pstPirDelayAttr)
{
    if (pstPirDelayAttr == NULL) {
        LOGE("Params is invalid\n");
        return -1;
    }
    
    HI_S32 ret = 0;
    HI_U32 timeoutMs = 1000;
    static char errCnt = 0;
    HI_UARTMSG_PARM_S  stSendMsg = {0};
    HI_UARTMSG_PARM_S  stWaitMsg = {0};

	stSendMsg.u32MsgId = HI_UARTMSG_S2M_GET_PIR_DELAY_TIME;
	stWaitMsg.u32MsgId = HI_UARTMSG_M2S_GET_PIR_DELAY_TIME_ACK;
	ret = HI_UARTMSG_SendMsgAndWaitMsg(&stSendMsg, &stWaitMsg, timeoutMs);
	if (0 != ret) {
		LOGE("HI_UARTMSG_SendMsgAndWaitMsg fail %d\n", ret);
		if (++errCnt >= 2) {
            mcusoc_set_reset("mcusoc_get_pir_delay_wakeup_time failed");
		}
		return -1;
	}

	pstPirDelayAttr->detectTimeSec = stWaitMsg.data[0];
	pstPirDelayAttr->triggerTimeSec = stWaitMsg.data[1];
	pstPirDelayAttr->intervalTimeSec = stWaitMsg.data[2];

    return 0;

}

int mcusoc_get_wakeup_type(SYSTEM_WAKEUP_TYPE_E *pWakeUpType)
{
    if (pWakeUpType == NULL) {
        LOGE("Params is invalid\n");
        return -1;
    }

//    static char getWifiWakeupReasonOnce = 0;
//    if (getWifiWakeupReasonOnce == 0) {  
//        WifiGetWakeupReason();
//        getWifiWakeupReasonOnce = 1;
//    }

    char *wakeupTypeString[] = {
        "power on",
        "bell key",     
        "pick key",    
        "netcfg key",     
        "pir",          
        "alarm",        
        "wifi",         
        "low power",          
        "wdt",          
        "usb charge",   
        "recovery wifi",  
        "unknown"
    };

    switch (g_enSocPowerType)
    {
        case HI_UARTMSG_POWER_PIR:
            *pWakeUpType = SYS_WAKEUP_TYPE_PIR;
            break;
        case HI_UARTMSG_POWER_REMOTE:
            *pWakeUpType = SYS_WAKEUP_TYPE_WIFI;
            break;
        case HI_UARTMSG_POWER_KEY:
            *pWakeUpType = SYS_WAKEUP_TYPE_KEY_BELL;
            break;
        case HI_UARTMSG_POWER_USB_INSERT:
            *pWakeUpType = SYS_WAKEUP_TYPE_USB_CHARGE;
            break;
        case HI_UARTMSG_POWER_RTC_WAKEUP:
            *pWakeUpType = SYS_WAEKUP_TYPE_ALARM;
            break;
        case HI_UARTMSG_POWER_LOW_ELECTRY:
            *pWakeUpType = SYS_WAKEUP_TYPE_LOW_POWER;
            break;  
        case HI_UARTMSG_POWER_BACK_DEFAULT:
        case HI_UARTMSG_POWER_LONGALIVE:
        case HI_UARTMSG_POWER_NORMAL:
            *pWakeUpType = SYS_WAKEUP_TYPE_POWER_ON;
             break;
        case HI_UARTMSG_POWER_WARNING:
            *pWakeUpType = SYS_WAKEUP_TYPE_KEY_PICK;
             break;
        case HI_UARTMSG_POWER_NETCFG:
            *pWakeUpType = SYS_WAKEUP_TYPE_KEY_NETCFG;
             break;             
        default:
            LOGW("WakeUpType %d is invalid\n", g_enSocPowerType);
            break;
    }
	if(*pWakeUpType != SYS_WAKEUP_TYPE_POWER_ON){
		LOGI("HI_UARTMSG_S2M_GET_POWER_ON_TYPE %d, pWakeUpType %s\n", g_enSocPowerType, wakeupTypeString[*pWakeUpType]);
	}

    return 0;
}

int mcusoc_get_battery_status(BATTERY_STATUS_S *pstBatStatus)
{
    if (pstBatStatus == NULL) {
        LOGE("Params is invalid\n");
        return -1;
    }
#if 0
    pstBatStatus->capacity = 80;
    pstBatStatus->chargingStatus = BAT_DISCHARGING;
#else   //从mcu拿数据有问题,临时屏蔽
	HI_UARTMSG_PARM_S  stSendMsg = {0};
	HI_UARTMSG_PARM_S  stWaitMsg = {0};
	HI_U32 timeoutMs = 1000;
	HI_S32 ret;
	static char errCnt = 0;
    static BATTERY_STATUS_S lastBatStatus = {0, BAT_DISCHARGING, 0};
    
	stSendMsg.u32MsgId = HI_UARTMSG_S2M_GET_POWERINFO;
	stWaitMsg.dataLen = 3;
	stWaitMsg.u32MsgId = HI_UARTMSG_M2S_GET_POWERINFO_ACK;
	ret = HI_UARTMSG_SendMsgAndWaitMsg(&stSendMsg, &stWaitMsg, timeoutMs);
	if (0 != ret)
	{
		LOGE("HI_UARTMSG_SendMsgAndWaitMsg fail %d\n", ret);
		if (++errCnt >= 2) {
            mcusoc_set_reset("mcusoc_get_battery_status failed");
		}		
		return -1;
	}
	else
	{
        unsigned short batValue = 0;
        memcpy(&batValue, stWaitMsg.data, sizeof(batValue));
        LOGI("battery capacity:%d\n", (int)batValue);
        
#ifdef BATTERY_TEST
        pstBatStatus->capacity = batValue;
        return 0;
#endif /* BATTERY_TEST */

        if (batValue >= gs_batteryLevel[9]) {
            pstBatStatus->capacity = 100;
        } else if (batValue >= gs_batteryLevel[8]) {
            pstBatStatus->capacity = 90;
        } else if (batValue >= gs_batteryLevel[7]) {
            pstBatStatus->capacity = 80;
        } else if (batValue >= gs_batteryLevel[6]) {
            pstBatStatus->capacity = 70;
        } else if (batValue >= gs_batteryLevel[5]) {
            pstBatStatus->capacity = 60;
        } else if (batValue >= gs_batteryLevel[4]) {
            pstBatStatus->capacity = 50;
        } else if (batValue >= gs_batteryLevel[3]) {
            pstBatStatus->capacity = 40;
        } else if (batValue >= gs_batteryLevel[2]) {
            pstBatStatus->capacity = 30;
        } else if (batValue >= gs_batteryLevel[1]) {
            pstBatStatus->capacity = 20;
            pstBatStatus->isLowBatState = 1;
        } else if (batValue >= gs_batteryLevel[0]) {
            pstBatStatus->capacity = 10;
			pstBatStatus->isLowBatState = 1;
        } else {
            pstBatStatus->capacity = 0;
            pstBatStatus->isLowBatState = 1;
        }
        
        if (batValue < 5500) { //用来判断是否接的是USB供电
            pstBatStatus->capacity = 100;
            pstBatStatus->isLowBatState = 0;
        }
        
        pstBatStatus->chargingStatus = BAT_DISCHARGING;

        if (lastBatStatus.capacity != 0 && pstBatStatus->capacity > lastBatStatus.capacity) {
            pstBatStatus->capacity = lastBatStatus.capacity;
            pstBatStatus->chargingStatus = lastBatStatus.chargingStatus;
            pstBatStatus->isLowBatState = lastBatStatus.isLowBatState;
        }

        lastBatStatus.capacity = pstBatStatus->capacity;
        lastBatStatus.chargingStatus = pstBatStatus->chargingStatus;
        lastBatStatus.isLowBatState = pstBatStatus->isLowBatState;
	}
#endif
	return 0;
}

int mcusoc_get_time(SYSTEM_TIME *pstSysTime)
{
    if (pstSysTime == NULL) {
        LOGE("Params is invalid\n");
        return -1;
    }

    int ret = 0;
    HI_U32 timeoutMs = 1000;
	HI_UARTMSG_PARM_S  stSendMsg = {0};
	HI_UARTMSG_PARM_S  stWaitMsg = {0};
    HI_DateTime stDataTime;
    static char errCnt = 0;

	stSendMsg.u32MsgId = HI_UARTMSG_S2M_GET_DATETIME;
	stWaitMsg.u32MsgId = HI_UARTMSG_M2S_GET_DATETIME_ACK;
	stWaitMsg.dataLen = sizeof(stDataTime);
	
	ret = HI_UARTMSG_SendMsgAndWaitMsg(&stSendMsg, &stWaitMsg, timeoutMs);
	if (0 != ret) {
		LOGE("HI_UARTMSG_SendMsgAndWaitMsg fail %d\n", ret);
		if (++errCnt >= 2) {
            mcusoc_set_reset("mcusoc_get_time failed");
		}		
		return -1;
	}

    memset(&stDataTime, 0, sizeof(stDataTime));


    LOGD("%x %x %x %x %x %x len:%d\n", stWaitMsg.data[0], stWaitMsg.data[1],stWaitMsg.data[2],stWaitMsg.data[3],stWaitMsg.data[4],
                                       stWaitMsg.data[5], stWaitMsg.dataLen);
    memcpy(&stDataTime, stWaitMsg.data, stWaitMsg.dataLen);

#if 1
    pstSysTime->year = stDataTime.year + 2000;
#else //临时规避MCU返回年份错误问题
    if (stDataTime.year == 21) {
        pstSysTime->year = 2019;
    } else if (stDataTime.year == 30) {
        pstSysTime->year = 2020;
    } else if (stDataTime.year == 31) {
        pstSysTime->year = 2021;
    } else {
        pstSysTime->year = stDataTime.year + 2000;
    }
#endif
    pstSysTime->month = stDataTime.month;
    pstSysTime->day = stDataTime.day;
    pstSysTime->hour = stDataTime.hour;
    pstSysTime->minute = stDataTime.minute;
    pstSysTime->second = stDataTime.second;

    LOGD("get mcu time: %02d-%02d-%02d %02d:%02d:%02d\n", pstSysTime->year, pstSysTime->month, pstSysTime->day,
                                                          pstSysTime->hour, pstSysTime->minute, pstSysTime->second);    
                                                          
    return 0;
}

int mcusoc_set_time(SYSTEM_TIME stSysTime)
{
    HI_UARTMSG_PARM_S sendMsg;
    HI_DateTime stDataTime;

    memset(&stDataTime, 0, sizeof(stDataTime));
    stDataTime.year = stSysTime.year - 2000;
    stDataTime.month = stSysTime.month;
    stDataTime.day = stSysTime.day;
    stDataTime.hour = stSysTime.hour;
    stDataTime.minute = stSysTime.minute;
    stDataTime.second = stSysTime.second;
    
    memset(&sendMsg, 0, sizeof(sendMsg));
    sendMsg.u32MsgId = HI_UARTMSG_S2M_SET_DATETIME;
    memcpy(sendMsg.data, &stDataTime, sizeof(stDataTime));
    sendMsg.dataLen = sizeof(stDataTime);
    HI_UARTMSG_SendMsg(&sendMsg);

    LOGD("set mcu time: %02d-%02d-%02d %02d:%02d:%02d\n", stSysTime.year, stSysTime.month, stSysTime.day,
                                                          stSysTime.hour, stSysTime.minute, stSysTime.second);
                                                          
    return 0;
}

int mcusoc_set_reset(char *reason)
{
    if (!UpgradeCheckIsRun()) {
        LOGW("reset mcu the reason: %s\n", reason);
        LOGW("Reset mcu !!!\n");
        usleep(200 * 1000);
        GpioSet(PRODUCT_GPIO_RESET_MCU);
    }

    return 0;
}

/**
 * @brief WiFi模块上电
 *
 * @param 无
 * 
 * @return |0|未升级| |非0|失败|
 *
 * @attention 无
 */
int mcusoc_set_wifi_power_on(void)
{
    int i = 0;
    HI_UARTMSG_PARM_S  stSendMsg = {0};

    memset(&stSendMsg, 0, sizeof(stSendMsg));
    stSendMsg.u32MsgId = HI_UARTMSG_S2M_SET_WIFI_POWER;
    stSendMsg.data[i++] = 0x1;
    stSendMsg.dataLen = i;

    HI_UARTMSG_SendMsg(&stSendMsg);

    return 0;
}

/**
 * @brief WiFi模块下电
 *
 * @param 无
 * 
 * @return |0|未升级| |非0|失败|
 *
 * @attention 无
 */
int mcusoc_set_wifi_power_off(void)
{
    LOGW("Test\n");
    
    int i = 0;
    HI_UARTMSG_PARM_S  stSendMsg = {0};

    memset(&stSendMsg, 0, sizeof(stSendMsg));
    stSendMsg.u32MsgId = HI_UARTMSG_S2M_SET_WIFI_POWER;
    stSendMsg.data[i++] = 0x0;
    stSendMsg.dataLen = i;

    HI_UARTMSG_SendMsg(&stSendMsg);

    return 0;    
}

/**
 * @brief 设置WiFi电源开关
 *
 * @param 无
 * 
 * @return |0|未升级| |非0|失败|
 *
 * @attention 无
 */
int mcusoc_set_wifi_power_switch(unsigned char switchState)
{
    LOGW("Test\n");
    
    int i = 0;
    HI_UARTMSG_PARM_S  stSendMsg = {0};

    memset(&stSendMsg, 0, sizeof(stSendMsg));
    stSendMsg.u32MsgId = HI_UARTMSG_S2M_SET_WIFI_POWER;
    stSendMsg.data[i++] = switchState;
    stSendMsg.dataLen = i;

    HI_UARTMSG_SendMsg(&stSendMsg);

    return 0;    
}

/**
 * @brief 主控下电
 *
 * @param 无
 * 
 * @return |0|未升级| |非0|失败|
 *
 * @attention 无
 */
int mcusoc_set_mainsoc_power_off(void)
{
    if (UpgradeCheckIsRun()) {
        LOGW("upgrade is running, stop soc poweroff!\n");
        return -1;
    }
    
    HI_UARTMSG_PARM_S  stSendMsg = {0};

    memset(&stSendMsg, 0, sizeof(stSendMsg));
    stSendMsg.u32MsgId = HI_UARTMSG_S2M_SOC_POWER_DOWN;

    HI_UARTMSG_SendMsg(&stSendMsg);
    
    return 0;
}

/**
 * @brief 主控维持自身电源
 *
 * @param 无
 * 
 * @return |0|未升级| |非0|失败|
 *
 * @attention 无
 */
int mcusoc_set_mainsoc_keep_power(void)
{
    GpioSet(PRODUCT_GPIO_KEEP_SELF_POWER);
    
    return 0;
}

/**
 * @brief 设置MCU看门狗使能状态
 *
 * @param[in] bEnalbe 使能状态 0:禁用 1:使能
 * 
 * @return |0|未升级| |非0|失败|
 *
 * @attention 无
 */
int mcusoc_set_wdg_state(char bEnable)
{
    int ret = 0;
    HI_U32 timeoutMs = 1000;
	HI_UARTMSG_PARM_S  stSendMsg = {0};
	HI_UARTMSG_PARM_S  stWaitMsg = {0};
    static char errCnt = 0;

	stSendMsg.u32MsgId = HI_UARTMSG_S2M_WDG_STATE_CFG;
	stWaitMsg.u32MsgId = HI_UARTMSG_M2S_WDG_STATE_CFG_ACK;
	if (bEnable) {
        stSendMsg.data[0] = 1;
	} else {
        stSendMsg.data[0] = 0;
	}
	stSendMsg.dataLen = 1;
	
	ret = HI_UARTMSG_SendMsgAndWaitMsg(&stSendMsg, &stWaitMsg, timeoutMs);
	if (0 != ret) {
		LOGE("HI_UARTMSG_SendMsgAndWaitMsg fail %d\n", ret);
		if (++errCnt >= 2) {
            mcusoc_set_reset("mcusoc_set_wdg_state failed");
		}		
		return -1;
	}

    gs_mcuState = bEnable;
    
    return 0;
}

/**
 * @brief 获取MCU看门狗使能状态
 *
 * @param[in] pState 状态 0:未使能 1:已使能
 * 
 * @return |0|未升级| |非0|失败|
 *
 * @attention 无
 */
int mcusoc_get_wdg_state(char *pState)
{
    *pState = gs_mcuState;
    
    return 0;
}

/**
 * @brief 配置MCU看门狗周期
 *
 * @param[in] time 看门狗周期时间
 * 
 * @return |0|未升级| |非0|失败|
 *
 * @attention 无
 */
int mcusoc_set_wdg_period(AV_U32 time)
{
    int ret = 0;
    HI_U32 timeoutMs = 1000;
	HI_UARTMSG_PARM_S  stSendMsg = {0};
	HI_UARTMSG_PARM_S  stWaitMsg = {0};
    static char errCnt = 0;

	stSendMsg.u32MsgId = HI_UARTMSG_S2M_WDG_TIME_CFG;
	stWaitMsg.u32MsgId = HI_UARTMSG_M2S_WDG_TIME_CFG_ACK;
    memcpy(stSendMsg.data, &time, sizeof(time));
    stSendMsg.dataLen = sizeof(time);
    
	ret = HI_UARTMSG_SendMsgAndWaitMsg(&stSendMsg, &stWaitMsg, timeoutMs);
	if (0 != ret) {
		LOGE("HI_UARTMSG_SendMsgAndWaitMsg fail %d\n", ret);
		if (++errCnt >= 2) {
            mcusoc_set_reset("mcusoc_set_wdt_period failed");
		}		
		return -1;
	}

    return 0;
}


/**
 * @brief MCU喂狗
 *
 * @param 无
 * 
 * @return |0|未升级| |非0|失败|
 *
 * @attention 无
 */
int mcusoc_set_wdg_feed(void)
{
    int ret = 0;
    HI_U32 timeoutMs = 1000;
	HI_UARTMSG_PARM_S  stSendMsg = {0};
	HI_UARTMSG_PARM_S  stWaitMsg = {0};
    static char errCnt = 0;

	stSendMsg.u32MsgId = HI_UARTMSG_S2M_WDG_FEED;
	stWaitMsg.u32MsgId = HI_UARTMSG_M2S_WDG_FEED_ACK;

	ret = HI_UARTMSG_SendMsgAndWaitMsg(&stSendMsg, &stWaitMsg, timeoutMs);
	if (0 != ret) {
		LOGE("HI_UARTMSG_SendMsgAndWaitMsg fail %d\n", ret);
		if (++errCnt >= 2) {
            mcusoc_set_reset("mcusoc_set_wdt_feed failed");
		}		
		return -1;
	}

    return 0;
}

int mcusoc_set_wifi_state(char state)
{
    int i = 0;
    HI_UARTMSG_PARM_S  stSendMsg = {0};

    memset(&stSendMsg, 0, sizeof(stSendMsg));
    stSendMsg.u32MsgId = HI_UARTMSG_S2M_SET_WIFI_STATUS;
    stSendMsg.data[i++] = (unsigned char)state;
    stSendMsg.dataLen = i;

    HI_UARTMSG_SendMsg(&stSendMsg);
    
	LOGD("set mcu wifi state: %d\n", state);
	
	return 0;
}

int mcusoc_get_wifi_state(char *pState)
{
    if (pState == NULL) {
        LOGE("Params is invalid\n");
        return -1;
    }
    
    int ret = 0;
    HI_U32 timeoutMs = 1000;
	HI_UARTMSG_PARM_S  stSendMsg = {0};
	HI_UARTMSG_PARM_S  stWaitMsg = {0};
    static char errCnt = 0;

	stSendMsg.u32MsgId = HI_UARTMSG_S2M_GET_WIFI_STATUS;
	stWaitMsg.u32MsgId = HI_UARTMSG_M2S_GET_WIFI_STATUS_ACK;

	ret = HI_UARTMSG_SendMsgAndWaitMsg(&stSendMsg, &stWaitMsg, timeoutMs);
	if (0 != ret) {
		LOGE("HI_UARTMSG_SendMsgAndWaitMsg fail %d\n", ret);
		if (++errCnt >= 2) {
            mcusoc_set_reset("mcusoc_get_wifi_state failed");
		}		
		return -1;
	}

    *pState = stWaitMsg.data[0];

    LOGD("get mcu wifi state: %d\n", *pState);
    
    return 0;
}

int mcusoc_set_sys_config(SOCSUB_SYS_CONFIG_S stMcuSysConfig)
{
	int i = 0;
    HI_UARTMSG_PARM_S  stSendMsg = {0};
    
    memset(&stSendMsg, 0, sizeof(stSendMsg));
    stSendMsg.u32MsgId = HI_UARTMSG_S2M_SET_DEFAULT_DATA;
    stSendMsg.data[i++] = stMcuSysConfig.socStartMaxSecond;
    stSendMsg.data[i++] = stMcuSysConfig.pirAlarmSwith;
    stSendMsg.data[i++] = stMcuSysConfig.pirAlarmInterval;
    stSendMsg.data[i++] = stMcuSysConfig.pirSensibility;
    stSendMsg.data[i++] = stMcuSysConfig.batteryLevel1Cfg;
    stSendMsg.data[i++] = stMcuSysConfig.batteryLevel2Cfg;
    stSendMsg.data[i++] = stMcuSysConfig.batteryLevel3Cfg;
    stSendMsg.data[i++] = stMcuSysConfig.keyResetTimeSeconds;
    stSendMsg.data[i++] = stMcuSysConfig.stopchecksocalive;
    stSendMsg.data[i++] = stMcuSysConfig.longAlive;
    stSendMsg.dataLen = i;
    
    HI_UARTMSG_SendMsg(&stSendMsg);
	
	return 0;
}

int mcusoc_get_sys_config(SOCSUB_SYS_CONFIG_S *pstMcuSysConfig)
{
    if (pstMcuSysConfig == NULL) {
        LOGE("Params is invalid\n");
        return -1;
    }
    
    int ret = 0;
    HI_U32 timeoutMs = 1000;
	HI_UARTMSG_PARM_S  stSendMsg = {0};
	HI_UARTMSG_PARM_S  stWaitMsg = {0};
    static char errCnt = 0;

    memset(&stSendMsg, 0, sizeof(stSendMsg));
    memset(&stWaitMsg, 0, sizeof(stWaitMsg));
	stSendMsg.u32MsgId = HI_UARTMSG_S2M_GET_DEFAULT_DATA;
	stWaitMsg.u32MsgId = HI_UARTMSG_M2S_GET_DEFAULT_DATA_ACK;

	ret = HI_UARTMSG_SendMsgAndWaitMsg(&stSendMsg, &stWaitMsg, timeoutMs);
	if (0 != ret) {
		LOGE("HI_UARTMSG_SendMsgAndWaitMsg fail %d\n", ret);
	#if 0
		if (++errCnt >= 2) {
            mcusoc_set_reset();
		}		
	#endif
		return -1;
	}

    pstMcuSysConfig->socStartMaxSecond   = stWaitMsg.data[0];
    pstMcuSysConfig->pirAlarmSwith       = stWaitMsg.data[1];
    pstMcuSysConfig->pirAlarmInterval    = stWaitMsg.data[2];
    pstMcuSysConfig->pirSensibility      = stWaitMsg.data[3];
    pstMcuSysConfig->batteryLevel1Cfg    = stWaitMsg.data[4];
    pstMcuSysConfig->batteryLevel2Cfg    = stWaitMsg.data[5];
    pstMcuSysConfig->batteryLevel3Cfg    = stWaitMsg.data[6];
    pstMcuSysConfig->keyResetTimeSeconds = stWaitMsg.data[7];
    pstMcuSysConfig->stopchecksocalive   = stWaitMsg.data[8];
    pstMcuSysConfig->longAlive           = stWaitMsg.data[9];
    
    return 0;
}

int mcusoc_set_alarm_wakeup(SOCSUB_ALARM_WAKEUP_ATTR_S stAlarmWakeupAttr)
{
	int i = 0;
    HI_UARTMSG_PARM_S  stSendMsg = {0};
    
    memset(&stSendMsg, 0, sizeof(stSendMsg));
    stSendMsg.u32MsgId = HI_UARTMSG_S2M_SET_TIMER_WAKEUP;
    stSendMsg.data[i++] = stAlarmWakeupAttr.minute;
    stSendMsg.data[i++] = stAlarmWakeupAttr.hour;
    stSendMsg.data[i++] = stAlarmWakeupAttr.bEnable;
    stSendMsg.dataLen = i;

    HI_UARTMSG_SendMsg(&stSendMsg);

    return 0;
}

int mcusoc_get_alarm_wakeup(SOCSUB_ALARM_WAKEUP_ATTR_S *pstAlarmWakeupAttr)
{
    if (pstAlarmWakeupAttr == NULL) {
        LOGE("Params is invalid\n");
        return -1;
    }   

    int ret = 0;
    HI_U32 timeoutMs = 1000;
	HI_UARTMSG_PARM_S  stSendMsg = {0};
	HI_UARTMSG_PARM_S  stWaitMsg = {0};
    static char errCnt = 0;

    memset(&stSendMsg, 0, sizeof(stSendMsg));
    memset(&stWaitMsg, 0, sizeof(stWaitMsg));
	stSendMsg.u32MsgId = HI_UARTMSG_S2M_GET_RTC_ALARM;
	stWaitMsg.u32MsgId = HI_UARTMSG_M2S_GET_RTC_ALARM_ACK;

	ret = HI_UARTMSG_SendMsgAndWaitMsg(&stSendMsg, &stWaitMsg, timeoutMs);
	if (0 != ret) {
		LOGE("HI_UARTMSG_SendMsgAndWaitMsg fail %d\n", ret);
	#if 0
		if (++errCnt >= 2) {
            mcusoc_set_reset();
		}		
	#endif
		return -1;
	}

    pstAlarmWakeupAttr->minute = stWaitMsg.data[0];
    pstAlarmWakeupAttr->hour = stWaitMsg.data[1];
    pstAlarmWakeupAttr->bEnable = stWaitMsg.data[2];
    
    return 0;
}

int mcusoc_check_is_support_update(void)
{
    int ret = 0;
    int bSupportUpdate = 0;
    
    char mcuVersion[32] = "";
    char configMcuVersion[32] = "";
    ret = mcusoc_get_version(mcuVersion);
    if (ret < 0) {
        LOGE("mcusoc_get_version failed\n");
        bSupportUpdate = 0;
    } else {
        bSupportUpdate = 1;
    }

    return bSupportUpdate;
}

int mcusoc_get_version(char *pVersion)
{
    if (pVersion == NULL) {
        LOGE("Params is invalid\n");
        return -1;
    }   

    int ret = 0;
    HI_U32 timeoutMs = 1000;
	HI_UARTMSG_PARM_S  stSendMsg = {0};
	HI_UARTMSG_PARM_S  stWaitMsg = {0};
    static char errCnt = 0;

    memset(&stSendMsg, 0, sizeof(stSendMsg));
    memset(&stWaitMsg, 0, sizeof(stWaitMsg));
	stSendMsg.u32MsgId = HI_UARTMSG_S2M_GET_MCU_VERSION;
	stWaitMsg.u32MsgId = HI_UARTMSG_M2S_GET_MCU_VERSION_ACK;

	ret = HI_UARTMSG_SendMsgAndWaitMsg(&stSendMsg, &stWaitMsg, timeoutMs);
	if (0 != ret) {
		LOGE("HI_UARTMSG_SendMsgAndWaitMsg fail %d\n", ret);
	#if 0
		if (++errCnt >= 2) {
            mcusoc_set_reset();
		}		
	#endif
		return -1;
	}

    memcpy(pVersion, stWaitMsg.data, stWaitMsg.dataLen);
    
    return 0;
}

/**
 * @brief 配置MCU监控SOC启动的时间
 *
 * @param[in] timeSec 监控描述
 * 
 * @return |0|未升级| |非0|失败|
 *
 * @attention 超过监控时间,即从启动到设置的监控时间内,都没有和MCU通信,则MCU会重启SOC
 */
int mcusoc_set_mainsoc_start_detect_time(int timeSec)
{
    int ret = 0;
    SOCSUB_SYS_CONFIG_S stMcuSysConfig;

    memset(&stMcuSysConfig, 0, sizeof(stMcuSysConfig));

    ret = mcusoc_get_sys_config(&stMcuSysConfig);
    if (ret < 0) {
        LOGE("mcusoc_get_sys_config failed\n");
        return -1;
    }

    stMcuSysConfig.socStartMaxSecond = timeSec;
    ret = mcusoc_set_sys_config(stMcuSysConfig);
    if (ret < 0) {
        LOGE("mcusoc_set_sys_config failed\n");
        return -1;
    }

    return 0;
}


/**
 * @brief 清除唤醒事件
 *
 * @param 无
 * 
 * @return |0|成功| |非0|失败|
 *
 * @attention 通知给MCU清除唤醒状态,另休眠时mcu也会主动清除,防止下次唤醒获取唤醒类型不正确
 */
int mcusoc_set_wakeup_event_clear(void)
{   
    HI_UARTMSG_PARM_S  stSendMsg = {0};
    
    memset(&stSendMsg, 0, sizeof(stSendMsg));
    stSendMsg.u32MsgId = HI_UARTMSG_S2M_CLR_WAKE_UP_EVENT;
    HI_UARTMSG_SendMsg(&stSendMsg);
    
    return 0;
}

int mcusoc_get_temperature(float *pTempValue)
{
    if (pTempValue == NULL) {
        LOGE("Params is invalid\n");
        return -1;
    }   

    int ret = 0;
    HI_U32 timeoutMs = 1000;
	HI_UARTMSG_PARM_S  stSendMsg = {0};
	HI_UARTMSG_PARM_S  stWaitMsg = {0};
    static char errCnt = 0;

    memset(&stSendMsg, 0, sizeof(stSendMsg));
    memset(&stWaitMsg, 0, sizeof(stWaitMsg));
	stSendMsg.u32MsgId = HI_UARTMSG_S2M_GET_TEMPERATURE;
	stWaitMsg.u32MsgId = HI_UARTMSG_M2S_GET_TEMPERATURE_ACK;

	ret = HI_UARTMSG_SendMsgAndWaitMsg(&stSendMsg, &stWaitMsg, timeoutMs);
	if (0 != ret) {
		LOGE("HI_UARTMSG_SendMsgAndWaitMsg fail %d\n", ret);
#if 0
		if (++errCnt >= 2) {
            mcusoc_set_reset();
		}		
#endif
		return -1;
	}

    char dataBuf[64] = "";
    memcpy(dataBuf, stWaitMsg.data, stWaitMsg.dataLen);

    LOGI("dataBuf: %s\n", dataBuf);

    int AvgTmp = 0;
    int Max = 0;
    int Min = 0;
    int Extremum = 0;

    sscanf(dataBuf, "AvgTmp=%x\nMax=%x\nMin=%x\nExtremum=%x", &AvgTmp, &Max, &Min, &Extremum);
    LOGI("AvgTmp:%d Max=%d Min=%d Extremum=%d\n", AvgTmp, Max, Min, Extremum);

    *pTempValue = AvgTmp/10 + ((AvgTmp%10) / 10.0);
    
    return 0;
}

static void  recv_mcu_event(HI_UARTMSG_PARM_S *pRcvMsg)
{
    if (UpgradeCheckIsRun()) {
        LOGW("upgrade is running!\n");
        return ;
    }
    
    switch (pRcvMsg->u32MsgId)
    {
        case HI_UARTMSG_M2S_PIR_ALARM: // PIR触发事件
            {
                LOGW(">>>>>>>> pir event\n");
#ifdef FAC_PIR_OSD_SHOW                
                static int count = 0;
                OsdDrawSetPir(count);
                count++;
#endif /* FAC_PIR_OSD_SHOW */


#ifdef YD_PROTOCOL
		PowerSetSocSleepTime(1, 20);
                MC_EVENT_ATTR_S stEventAttr;
                memset(&stEventAttr, 0, sizeof(stEventAttr));
                stEventAttr.bPIREvent = 1;
		stEventAttr.PIREvent_utcms = get_utc_ms();
                DOTSetEventState(&stEventAttr);
#endif /* YD_PROTOCOL */
            }
            break;
        case HI_UARTMSG_M2S_EXTERNALPOWERIN: // 外部电源接入事件
            break;
        case HI_UARTMSG_M2S_EXTERNALPOWEROUT: // 外部电源拔出事件
            break;
    }
}

int mcusoc_init(void)
{
#if 0
    PIR_DELAY_WAKEUP_ATTR_S stPirDelayAttr;

    /* set pir interval time */
    memset(&stPirDelayAttr, 0, sizeof(stPirDelayAttr));
    stPirDelayAttr.detectTimeSec = 0;
    stPirDelayAttr.triggerTimeSec = 0;
    stPirDelayAttr.intervalTimeSec = 5;
    mcusoc_set_pir_delay_wakeup_time(stPirDelayAttr);
#endif

    int ret = 0;

    ret = HI_UARTMSG_Init();
    if (ret < 0) {
        LOGE("HI_UARTMSG_Init failed\n");
        return -1;
    }

    /* register recv key event from uart */
    HI_UARTMSG_RegRecvCbk(recv_mcu_event);

    return 0;
}

int mcusoc_deinit(void)
{
    HI_UARTMSG_Deinit();
    
    HI_UARTMSG_RegRecvCbk(recv_mcu_event);
    
    return 0;
}


